﻿using FSLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting;
using System.Text;
using System.Threading.Tasks;

namespace CSApp.BC
{
	/// <summary>
	/// フィルタ種別
	/// </summary>
	public enum FilterType
	{
		// NOTE:フィルタの種別が増えたら、ここに追加
		Unknown,
		Filter2D,
		Filter3D,
		Analysis
	}

	/// <summary>
	/// フィルタの管理クラス
	/// </summary>
	public class FilterManager
	{
		/// <summary>
		/// フィルタのアセンブリ名
		/// </summary>
		private const string FILTER_ASSEMBLY = "FSLib";

		/// <summary>
		/// フィルタを列挙する
		/// </summary>
		/// <returns></returns>
		public static List<FilterItem> EnumFilters()
		{
			List<FilterItem> items = new List<FilterItem>();

			// 対象アセンブリのロード
			Assembly asm = Assembly.Load(FILTER_ASSEMBLY);

			// アセンブリに含まれる全タイプから有効なフィルタを抽出
			Type[] types = asm.GetTypes();
			foreach (var type in types)
			{
				FilterType ft = getFilterType(type);
				if (ft != FilterType.Unknown)
				{
					// 有効なフィルタのみ追加
					object instance = Activator.CreateInstance(type);
					items.Add(new FilterItem(ft, instance));
				}
			}

			items.Sort();
			return items;
		}

		/// <summary>
		/// Typeからフィルタ種別を判定。
		/// </summary>
		/// <param name="type"></param>
		/// <returns></returns>
		private static FilterType getFilterType(Type type)
		{
			// 妥当性チェック
			if (!type.IsClass) return FilterType.Unknown;
			if (!type.IsPublic) return FilterType.Unknown;

			// 実装しているInterfaceを判定
			foreach (var i in type.GetInterfaces())
			{
				// NOTE:フィルタの種別が増えたら、ここに追加
				if (i == typeof(IFilter2D)) return FilterType.Filter2D;
				if (i == typeof(IFilter3D)) return FilterType.Filter3D;
				if (i == typeof(IAnalysis)) return FilterType.Analysis;
			}

			// どれにも該当しない場合
			return FilterType.Unknown;
		}
	}
}
